package com.quectel.cms.controller.datav;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.grid.GridMemberBindResourcesBusiness;
import com.quectel.business.common.util.sys.SysCodeUtils;
import com.quectel.cms.controller.BaseController;
import com.quectel.cms.controller.grid.helper.GridHelper;
import com.quectel.cms.util.SessionHolder;
import com.quectel.cms.vo.datav.DataVGridCompanyVo;
import com.quectel.cms.vo.datav.DataVGridHouseholdVo;
import com.quectel.cms.vo.grid.GridMemberEvaluateAssessRecordVo;
import com.quectel.constant.core.grid.GridConstant;
import com.quectel.constant.global.StatisticsConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.sys.SysCodeKeyConstants;
import com.quectel.core.module.grid.dto.*;
import com.quectel.core.module.grid.service.*;
import com.quectel.core.module.grid.vo.GridEventRecordEventCountVo;
import com.quectel.core.module.grid.vo.GridEventRecordStatusCountVo;
import com.quectel.core.module.household.dto.HouseholdDto;
import com.quectel.core.module.household.dto.datav.CompanyCountDto;
import com.quectel.core.module.household.dto.datav.FocusGroupsCountDto;
import com.quectel.core.module.household.dto.datav.HouseholdCountDto;
import com.quectel.core.module.household.service.HouseholdRoomService;
import com.quectel.core.module.household.service.HouseholdService;
import com.quectel.core.module.really.dto.ReallyCompanyDto;
import com.quectel.core.module.really.service.ReallyCompanyService;
import com.quectel.core.module.village.dto.VillageBuildingDto;
import com.quectel.core.module.village.dto.datav.BuildingRoomHouseholdCount;
import com.quectel.core.module.village.service.VillageBuildingService;
import com.quectel.core.module.village.service.VillageRoomService;
import com.quectel.sys.module.sys.dto.SysCodeDto;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yubobo
 * @email bobo.yu@quectel.com
 * @date 2022/3/10 上午9:17
 */
@RestController
@RequestMapping("datav/grid")
@Tag(name = "DataVGridController", description = "大屏-网格管理相关接口")
@Slf4j
public class DataVGridController extends BaseController {

    public static final String BUILDING_IDS = "buildingIds";
    public static final String COMPANY_IDS = "companyIds";
    public static final String ZERO_PERCENT = "0.00%";

    @DubboReference
    private GridService gridService;
    @DubboReference
    private HouseholdService householdService;
    @DubboReference
    private HouseholdRoomService householdRoomService;
    @DubboReference
    private VillageBuildingService villageBuildingService;
    @DubboReference
    private VillageRoomService villageRoomService;
    @DubboReference
    private GridBindingService gridBindingService;
    @DubboReference
    private ReallyCompanyService reallyCompanyService;
    @DubboReference
    private GridMemberService gridMemberService;
    @DubboReference
    private GridMemberEvaluateService gridMemberEvaluateService;
    @DubboReference
    private GridEventRecordService gridEventRecordService;
    @DubboReference
    private GridPrimaryEventService gridPrimaryEventService;
    @DubboReference
    private GridMemberGridBindingService gridMemberGridBindingService;

    @Autowired
    private GridMemberBindResourcesBusiness gridMemberBindResourcesBusiness;
    @Autowired
    private GridHelper gridHelper;

    /**
     * 通过网格id 获取网格下的网格员列表; 不分页
     */
    @GetMapping("queryMemberListByGridId")
    @Operation(summary = "通过网格id不分页获取网格下的网格员列表")
    public Response<List<GridMemberDto>> queryMemberListByGridId(@Parameter(description = "网格id") Long gridId) {

        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        List<GridMemberDto> list = new ArrayList<>();

        List<GridMemberGridBindingDto> resultList = gridMemberGridBindingService.queryList(request.getParams());
        if (CollectionUtils.isNotEmpty(resultList)) {
            for (GridMemberGridBindingDto memberGridBinding : resultList) {
                GridMemberDto gridMemberDto = gridMemberService.selectCacheById(memberGridBinding.getGridMemberId());
                List<Long> grids = gridMemberBindResourcesBusiness.getGridIdByGridMember(gridMemberDto);
                if (CollectionUtils.isNotEmpty(grids)) {
                    StringBuilder builder = new StringBuilder();
                    for (Long recordGridId : grids) {
                        GridDto gridDto = gridService.selectCacheById(recordGridId);
                        if (gridDto != null) {
                            StringBuilder append = builder.append(gridDto.getName()).append(";");
                            gridMemberDto.setGridNameString(append.toString());
                        }
                    }
                }
                if (gridMemberDto.getStatus().equals(SystemConstants.YES)) {
                    list.add(gridMemberDto);
                }
            }
        } else {
            list = new ArrayList<>();
        }

        return Response.<List<GridMemberDto>>ok().wrap(list);
    }


    /**
     * 网格上报事件
     * GridEventRecordController
     *
     */


    /**
     * 事件动态,各个状态事件的统计
     */
    @GetMapping("statusCount")
    @Operation(summary = "事件动态,各个状态事件的统计")
    public Response<List<GridEventRecordStatusCountVo>> statusCount(
            @Parameter(description = "时:HOUR 日：DAY 周：MONTH 月：MONTH 默认按日")
            @RequestParam(required = false, defaultValue = StatisticsConstants.TIME_RANGE_BY_DAY) String type,
            @Parameter(description = "小区ID") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格ID") @RequestParam(required = false) Long gridId

    ) {
        //处理数据
        List<GridEventRecordStatusCountVo> result = new ArrayList<>();
        //查询字典值
        List<SysCodeDto> sysCodeDtos = SysCodeUtils.easyToGetByMark(SysCodeKeyConstants.GRID_EVENT_RECORD_STATUS);

        //查看当前所处区域等级
        List<GridRegionInfoDto> gridRegionInfoDtos = gridHelper.queryRegionInfoByGroupId(SessionHolder.getSysUser().getGroupId());

        if (CollectionUtils.isEmpty(gridRegionInfoDtos)) {
            for (SysCodeDto sysCodeDto : sysCodeDtos) {
                GridEventRecordStatusCountVo build = GridEventRecordStatusCountVo.builder().status(Byte.valueOf(sysCodeDto.getValue())).statusName(sysCodeDto.getName()).build();
                build.setStatusCount(0);
                result.add(build);
            }
            return Response.<List<GridEventRecordStatusCountVo>>ok().wrap(result);
        }

        Map<String, Object> params = new HashMap<>(4);
        params.put(LambdaUtil.getFieldName(GridEventRecordDto::getTenantId), SessionHolder.getSysUser().getTenantId());

        List<String> codes = gridRegionInfoDtos.stream().map(GridRegionInfoDto::getCode).collect(Collectors.toList());
        //如果是区
        if (GridConstant.RegionLevel.DISTRICT_LEVEL.getLevel().equals(gridRegionInfoDtos.get(0).getLevel())) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getDistrictCode), codes.get(0));
        } else if (GridConstant.RegionLevel.STREET_LEVEL.getLevel().equals(gridRegionInfoDtos.get(0).getLevel())) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getStreetCode), codes.get(0));
        } else if (GridConstant.RegionLevel.VILLAGE_LEVEL.getLevel().equals(gridRegionInfoDtos.get(0).getLevel())) {
            params.put(GridConstant.VILLAGE_IDS, codes);
        } else {
            return Response.<List<GridEventRecordStatusCountVo>>ok().wrap(Collections.emptyList());
        }
        if (villageId != null) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getVillageId), villageId);
        }
        if (gridId != null) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getGridId), gridId);
        }

        //获取日期
        Pair<String, String> startAndEndTime = gridHelper.getStartAndEndTime(type);
        params.put(GridConstant.EVENT_CREATE_DATE_SLOT_KEY_PAIR.getLeft(), startAndEndTime.getLeft());
        params.put(GridConstant.EVENT_CREATE_DATE_SLOT_KEY_PAIR.getRight(), startAndEndTime.getRight());
        //查询数据库
        List<GridEventRecordStatusCountVo> countVos = gridEventRecordService.statusCount(params);

        Map<Byte, GridEventRecordStatusCountVo> countVoMap = new HashMap<>(sysCodeDtos.size());
        //转为map
        if (CollectionUtils.isNotEmpty(countVos)) {
            countVoMap = countVos.stream().collect(Collectors.toMap(GridEventRecordStatusCountVo::getStatus, Function.identity(), (key1, key2) -> key2));
        }

        for (SysCodeDto sysCodeDto : sysCodeDtos) {
            GridEventRecordStatusCountVo build = GridEventRecordStatusCountVo.builder().status(Byte.valueOf(sysCodeDto.getValue())).statusName(sysCodeDto.getName()).build();

            GridEventRecordStatusCountVo countVo = countVoMap.get(Byte.valueOf(sysCodeDto.getValue()));
            build.setStatusCount(countVo != null ? countVo.getStatusCount() : 0);
            result.add(build);

        }

        return Response.<List<GridEventRecordStatusCountVo>>ok().wrap(result);
    }

    /**
     * 事件类型统计,各个一级事件类型的统计
     */
    @GetMapping("eventCount")
    @Operation(summary = "事件类型统计,各个一级事件类型的统计")
    public Response<List<GridEventRecordEventCountVo>> eventCount(
            @Parameter(description = "时:HOUR 日：DAY 周：MONTH 月：MONTH 默认按日")
            @RequestParam(required = false, defaultValue = StatisticsConstants.TIME_RANGE_BY_DAY) String type,
            @Parameter(description = "小区ID") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格ID") @RequestParam(required = false) Long gridId

    ) {
        //处理数据
        List<GridEventRecordEventCountVo> result = new ArrayList<>();

        //查询租户所有的一级事件
        Map<String, Object> primaryEventParams = new HashMap<>();
        primaryEventParams.put(LambdaUtil.getFieldName(GridPrimaryEventDto::getTenantId), SessionHolder.getSysUser().getTenantId());
        List<GridPrimaryEventDto> gridPrimaryEventDtos = gridPrimaryEventService.queryList(primaryEventParams);

        //查看当前所处区域等级
        List<GridRegionInfoDto> gridRegionInfoDtos = gridHelper.queryRegionInfoByGroupId(SessionHolder.getSysUser().getGroupId());

        if (CollectionUtils.isEmpty(gridRegionInfoDtos)) {

            for (GridPrimaryEventDto primaryEventDto : gridPrimaryEventDtos) {
                GridEventRecordEventCountVo build = GridEventRecordEventCountVo.builder().eventPrimaryId(primaryEventDto.getId()).eventPrimaryName(primaryEventDto.getName()).build();
                build.setEventCount(0);
                result.add(build);
            }

            return Response.<List<GridEventRecordEventCountVo>>ok().wrap(result);
        }

        Map<String, Object> params = new HashMap<>(4);
        params.put(LambdaUtil.getFieldName(GridEventRecordDto::getTenantId), SessionHolder.getSysUser().getTenantId());


        List<String> codes = gridRegionInfoDtos.stream().map(GridRegionInfoDto::getCode).collect(Collectors.toList());
        //如果是区
        if (GridConstant.RegionLevel.DISTRICT_LEVEL.getLevel().equals(gridRegionInfoDtos.get(0).getLevel())) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getDistrictCode), codes.get(0));
        } else if (GridConstant.RegionLevel.STREET_LEVEL.getLevel().equals(gridRegionInfoDtos.get(0).getLevel())) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getStreetCode), codes.get(0));
        } else if (GridConstant.RegionLevel.VILLAGE_LEVEL.getLevel().equals(gridRegionInfoDtos.get(0).getLevel())) {
            params.put(GridConstant.VILLAGE_IDS, codes);
        } else {
            return Response.<List<GridEventRecordEventCountVo>>ok().wrap(Collections.emptyList());
        }

        if (villageId != null) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getVillageId), villageId);
        }
        if (gridId != null) {
            params.put(LambdaUtil.getFieldName(GridEventRecordDto::getGridId), gridId);
        }

        //获取日期
        Pair<String, String> startAndEndTime = gridHelper.getStartAndEndTime(type);
        params.put(GridConstant.EVENT_CREATE_DATE_SLOT_KEY_PAIR.getLeft(), startAndEndTime.getLeft());
        params.put(GridConstant.EVENT_CREATE_DATE_SLOT_KEY_PAIR.getRight(), startAndEndTime.getRight());

        //查询数据库
        List<GridEventRecordEventCountVo> countVos = gridEventRecordService.eventCount(params);


        assert CollectionUtils.isNotEmpty(gridPrimaryEventDtos);
        Map<Long, GridEventRecordEventCountVo> countVoMap = new HashMap<>(gridPrimaryEventDtos.size());
        //转为map
        if (CollectionUtils.isNotEmpty(countVos)) {
            countVoMap = countVos.stream().collect(Collectors.toMap(GridEventRecordEventCountVo::getEventPrimaryId, Function.identity(), (key1, key2) -> key2));
        }

        for (GridPrimaryEventDto primaryEventDto : gridPrimaryEventDtos) {
            GridEventRecordEventCountVo build = GridEventRecordEventCountVo.builder().eventPrimaryId(primaryEventDto.getId()).eventPrimaryName(primaryEventDto.getName()).build();

            GridEventRecordEventCountVo countVo = countVoMap.get(primaryEventDto.getId());
            build.setEventCount(countVo != null ? countVo.getEventCount() : 0);
            result.add(build);
        }

        return Response.<List<GridEventRecordEventCountVo>>ok().wrap(result);
    }


    /**
     * 网格员评估列表
     */
    @GetMapping("gridMemberEvaluateList")
    @Operation(summary = "网格员评估的分页查询列表")
    public Response<Page<GridMemberEvaluateDto>> gridMemberEvaluateList(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId,
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());

        // 查询社区下的网格ids
        Map<String, Object> gridSqlMap = new HashMap<>();

        if (gridId != null) {
            gridSqlMap.put(LambdaUtil.getFieldName(GridMemberGridBindingDto::getGridId), gridId);
        } else {
            gridSqlMap.put(LambdaUtil.getFieldName(GridDto::getVillageId), villageId);
            List<GridDto> gridDtos = gridService.queryList(gridSqlMap);
            Set<Long> collect = gridDtos.stream().map(GridDto::getId).collect(Collectors.toSet());
            List<Long> gridIds = new ArrayList<>(collect);

            // 查询网格下的网格员id
            gridSqlMap.clear();
            gridSqlMap.put(GridConstant.GRID_IDS, gridIds);
        }

        List<GridMemberGridBindingDto> gridMemberGridBindingDtos = gridMemberGridBindingService.queryList(gridSqlMap);
        Set<Long> memberCollect = gridMemberGridBindingDtos.stream().map(GridMemberGridBindingDto::getGridMemberId).collect(Collectors.toSet());
        List<Long> gridMemberIds = new ArrayList<>(memberCollect);

        List<Long> effectiveMemberIds = new ArrayList<>();
        for (int i = 0; i < gridMemberIds.size(); i++) {
            GridMemberDto gridMemberDto = gridMemberService.selectCacheById(gridMemberIds.get(i));
            if (gridMemberDto != null && (gridMemberDto.getStatus().equals(SystemConstants.YES))) {
                effectiveMemberIds.add(gridMemberDto.getId());
            }
        }

        request.put("gridMemberIds", effectiveMemberIds);
        int total = gridMemberEvaluateService.queryTotal(request.getParams());

        List<GridMemberEvaluateDto> list = null;
        if (total > 0) {
            list = gridMemberEvaluateService.queryList(request.getParams());
            for (GridMemberEvaluateDto evaluateDto : list) {
                List<GridDto> grids = evaluateDto.getGrids();
                if (CollectionUtils.isNotEmpty(grids)) {
                    StringBuilder builder = new StringBuilder();
                    for (GridDto grid : grids) {
                        // 网格id 不为空，只显示这个小区的
                        if (gridId == null) {
                            if (grid != null && grid.getVillageId().equals(villageId)) {
                                StringBuilder append = builder.append(grid.getName()).append(";");
                                evaluateDto.setGridNameString(append.toString());
                            }
                        } else {
                            // 网格id 不为空，只显示这个网格的
                            if (grid != null && grid.getVillageId().equals(villageId) && grid.getId().equals(gridId)) {
                                StringBuilder append = builder.append(grid.getName()).append(";");
                                evaluateDto.setGridNameString(append.toString());
                            }
                        }
                    }
                }

                String assessRecordJson = evaluateDto.getAssessRecordJson();
                if (StringUtils.isNotBlank(assessRecordJson)) {
                    GridMemberEvaluateAssessRecordVo parse = JacksonUtils.parse(assessRecordJson, GridMemberEvaluateAssessRecordVo.class);
                    DecimalFormat df = new DecimalFormat();
                    BigDecimal dividend = new BigDecimal(parse.getTotal());
                    Integer finishedTotal = parse.getFinishedTotal();
                    Integer rejectedTotal = parse.getRejectedTotal();
                    Integer expiredTotal = parse.getExpiredTotal();
                    if (finishedTotal > 0) {
                        BigDecimal finished = new BigDecimal(finishedTotal);
                        BigDecimal recordfinishedResult = finished.divide(dividend, 2, RoundingMode.HALF_UP);
                        String finishedRate = df.format(recordfinishedResult);
                        evaluateDto.setFinishedRate(finishedRate);
                    } else {
                        evaluateDto.setFinishedRate(ZERO_PERCENT);
                    }

                    if (rejectedTotal > 0) {
                        BigDecimal rejected = new BigDecimal(rejectedTotal);
                        BigDecimal recordRejectedResult = rejected.divide(dividend, 2, RoundingMode.HALF_UP);
                        String rejectedRate = df.format(recordRejectedResult);
                        evaluateDto.setRejectedRate(rejectedRate);
                    } else {
                        evaluateDto.setRejectedRate(ZERO_PERCENT);
                    }

                    if (expiredTotal > 0) {
                        BigDecimal expired = new BigDecimal(expiredTotal);
                        BigDecimal recordExpiredResult = expired.divide(dividend, 2, RoundingMode.HALF_UP);
                        String expiredRate = df.format(recordExpiredResult);
                        evaluateDto.setExpiredRate(expiredRate);
                    } else {
                        evaluateDto.setExpiredRate(ZERO_PERCENT);
                    }
                } else {
                    evaluateDto.setFinishedRate(ZERO_PERCENT);
                    evaluateDto.setExpiredRate(ZERO_PERCENT);
                    evaluateDto.setRejectedRate(ZERO_PERCENT);
                }
            }

        } else {
            list = new ArrayList<>();
        }
        Page<GridMemberEvaluateDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<GridMemberEvaluateDto>>ok().wrap(page);
    }


    /**
     * 实有单位类型统计
     *
     * @param villageId
     * @param gridId
     * @return
     */
    @GetMapping("companyGroupsCount")
    @Operation(summary = "实有单位统计")
    public Response<List<CompanyCountDto>> companyGroupsCount(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId
    ) {
        Map<String, Object> params = Request.parseParams(httpServletRequest);
        super.fillAuthorityData(params);

        List<SysCodeDto> sysCodeDtos = SysCodeUtils.easyToGetByMark(SysCodeKeyConstants.COMPANY_TYPE);
        List<CompanyCountDto> result = new ArrayList<>();

        for (SysCodeDto sysCode : sysCodeDtos) {
            CompanyCountDto countRecord = new CompanyCountDto();
            countRecord.setType(Convert.toByte(sysCode.getValue()));
            countRecord.setName(sysCode.getName());
            countRecord.setCount(0);
            result.add(countRecord);
        }

        // 精准网格
        if (gridId != null) {
            List<Long> sourceIds = gridMemberBindResourcesBusiness.getSourceIdByGridIdAndSourceType(gridId, GridConstant.SourceType.COMPANY.getType());
            params.put(COMPANY_IDS, sourceIds);
        }
        List<CompanyCountDto> companyCountDto = reallyCompanyService.countCompany(params);
        if (CollectionUtils.isNotEmpty(companyCountDto)) {
            for (CompanyCountDto companyCount : result) {
                Byte type = companyCount.getType();
                for (CompanyCountDto sqlRecord : companyCountDto) {
                    if (sqlRecord.getType().equals(type)) {
                        companyCount.setCount(sqlRecord.getCount());
                    }
                }
            }
        }
        return Response.<List<CompanyCountDto>>ok().wrap(result);
    }

    /**
     * @param villageId
     * @param gridId
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("companyList")
    @Operation(summary = "实有单位的分页查询列表")
    public Response<Page<DataVGridCompanyVo>> companyList(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId,
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        GridDto grid = new GridDto();
        // 精准网格
        if (gridId != null) {
            grid = gridService.selectCacheById(gridId);
            List<Long> sourceIds = gridMemberBindResourcesBusiness.getSourceIdByGridIdAndSourceType(gridId, GridConstant.SourceType.COMPANY.getType());
            request.getParams().put(COMPANY_IDS, sourceIds);
        }

        int total = reallyCompanyService.queryTotal(request.getParams());
        List<ReallyCompanyDto> list = null;
        List<DataVGridCompanyVo> recordList = new ArrayList<>();
        if (total > 0) {
            list = reallyCompanyService.queryList(request.getParams());
            for (ReallyCompanyDto reallyCompanyDto : list) {
                DataVGridCompanyVo companyVo = new DataVGridCompanyVo();
                companyVo.setName(reallyCompanyDto.getName());
                companyVo.setType(reallyCompanyDto.getType());
                companyVo.setIndustryType(reallyCompanyDto.getIndustryType());
                if (gridId != null) {
                    companyVo.setGridName(grid.getName());
                } else {
                    GridBindingDto binding = gridBindingService.selectOne(GridConstant.SourceType.COMPANY.getType(), reallyCompanyDto.getId());
                    if (binding != null) {
                        GridDto gridRecod = gridService.selectCacheById(binding.getGridId());
                        if (gridRecod != null) {
                            companyVo.setGridName(gridRecod.getName());
                        }
                    }
                }
                recordList.add(companyVo);
            }
        } else {
            recordList = new ArrayList<>();
        }
        Page<DataVGridCompanyVo> page = new Page<>(request.getPageNo(), request.getPageSize(), total, recordList);
        return Response.<Page<DataVGridCompanyVo>>ok().wrap(page);
    }

    @GetMapping("buildingCount")
    @Operation(summary = "楼栋信息相关统计")
    public Response<BuildingRoomHouseholdCount> buildingCount(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "楼栋id") @RequestParam(required = false) Long buildingId
    ) {
        Map<String, Object> params = Request.parseParams(httpServletRequest);
        super.fillAuthorityData(params);

        BuildingRoomHouseholdCount buildingRoomHouseholdCount = new BuildingRoomHouseholdCount();
        buildingRoomHouseholdCount.setHouseholdCountDto(householdService.countHousehold(params));
        buildingRoomHouseholdCount.setRoomCountDto(villageRoomService.countRoom(params));

        return Response.<BuildingRoomHouseholdCount>ok().wrap(buildingRoomHouseholdCount);
    }


    @GetMapping("queryByVillageId")
    @Operation(summary = "通过小区id查询楼栋列表")
    public Response<List<VillageBuildingDto>> queryByVillageId(
            @Parameter(description = "小区") @RequestParam Long villageId,
            @Parameter(description = "网格id") @RequestParam Long gridId
    ) {
        List<VillageBuildingDto> villageBuildingDtos = new ArrayList<>();
        if (gridId == null) {
            villageBuildingDtos = villageBuildingService.selectByVillageId(villageId);
        } else {
            List<GridBindingDto> gridBindingDtos = gridBindingService.selectListByGridIdAndSourceType(gridId, GridConstant.SourceType.BUILDING.getType());
            for (GridBindingDto bindDto : gridBindingDtos) {
                VillageBuildingDto villageBuildingDto = villageBuildingService.selectById(bindDto.getSourceId());
                if (villageBuildingDto != null) {
                    villageBuildingDtos.add(villageBuildingDto);
                }
            }
        }
        return Response.<List<VillageBuildingDto>>ok().wrap(villageBuildingDtos);
    }

    /**
     * 小区 / 网格重点人员统计
     *
     * @param villageId
     * @param gridId
     * @return
     */
    @GetMapping("focusGroupsCount")
    @Operation(summary = "重点人员数据统计")
    public Response<List<FocusGroupsCountDto>> focusGroupsCount(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId
    ) {
        Map<String, Object> params = Request.parseParams(httpServletRequest);
        super.fillAuthorityData(params);

        List<SysCodeDto> sysCodeDtos = SysCodeUtils.easyToGetByMark(SysCodeKeyConstants.HOUSEHOLD_TAG);
        //sysCodeDto在core-service不存在所以转为map(这里不转map dubbo也会自动转)
        params.put("tags", sysCodeDtos.stream().map(v -> BeanUtil.beanToMap(v)).collect(Collectors.toList()));

        // 精准网格
        if (gridId != null) {
            List<Long> sourceIds = gridMemberBindResourcesBusiness.getSourceIdByGridIdAndSourceType(gridId, GridConstant.SourceType.BUILDING.getType());
            params.put(BUILDING_IDS, sourceIds);
        }

        Map<String, Double> result = householdService.focusGroupsCount(params);

        List<FocusGroupsCountDto> list = new ArrayList<>();
        for (Map.Entry<String, Double> entry : result.entrySet()) {
            FocusGroupsCountDto focusGroupsCountDto = new FocusGroupsCountDto();
            focusGroupsCountDto.setName(SysCodeUtils.easyToGetName(SysCodeKeyConstants.HOUSEHOLD_TAG, entry.getKey()));
            focusGroupsCountDto.setCount(entry.getValue().intValue());
            list.add(focusGroupsCountDto);
        }

        // 前端要求返回空巢老人在末尾，并且按名字长度排序
        Collections.sort(list, (o1, o2) -> {
            if (o1.getName().equals("空巢老人")) {
                return 1;
            }
            if (o2.getName().equals("空巢老人")) {
                return -1;
            }
            return o2.getName().length() - o1.getName().length();
        });

        return Response.<List<FocusGroupsCountDto>>ok().wrap(list);
    }

    /**
     * 小区 / 网格下- 实有人口列表
     *
     * @param villageId
     * @param gridId
     * @return
     */
    @GetMapping("reallyHouseholdList")
    @Operation(summary = "实有人口的分页查询列表")
    public Response<Page<DataVGridHouseholdVo>> reallyHouseholdList(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId,
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        GridDto grid = new GridDto();
        // 精准网格
        if (gridId != null) {
            grid = gridService.selectCacheById(gridId);
            List<Long> sourceIds = gridMemberBindResourcesBusiness.getSourceIdByGridIdAndSourceType(gridId, GridConstant.SourceType.BUILDING.getType());
            request.getParams().put(BUILDING_IDS, sourceIds);
        }

        int total = householdService.queryTotal(request.getParams());
        List<HouseholdDto> list = null;
        List<DataVGridHouseholdVo> recordList = new ArrayList<>();
        if (total > 0) {
            list = householdService.queryList(request.getParams());
            for (HouseholdDto householdDto : list) {
                DataVGridHouseholdVo householdRecord = new DataVGridHouseholdVo();
                householdRecord.setName(householdDto.getName());
                householdRecord.setGender(householdDto.getGender());
                householdRecord.setType(householdDto.getType());
                if (gridId != null) {
                    householdRecord.setGridName(grid.getName());
                } else {
                    householdDto.setHouseholdRoomDtoList(householdRoomService.selectByHouseholdId(householdDto.getId()));
                    householdRecord.setGridName(householdDto.getHouseholdRoomDtoList().get(0).getGridName());
                }
                recordList.add(householdRecord);
            }
        } else {
            recordList = new ArrayList<>();
        }

        Page<DataVGridHouseholdVo> page = new Page<>(request.getPageNo(), request.getPageSize(), total, recordList);
        return Response.<Page<DataVGridHouseholdVo>>ok().wrap(page);
    }

    /**
     * 小区 / 网格- 实有人口统计
     * 人口总数
     * 常住人口
     * 流动人口
     */
    @GetMapping("reallyHouseholdStatistics")
    @Operation(summary = "实有人口统计")
    public Response<HouseholdCountDto> reallyHouseholdStatistics(
            @Parameter(description = "小区id") @RequestParam(required = false) Long villageId,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId) {
        Map<String, Object> params = Request.parseParams(httpServletRequest);
        super.fillAuthorityData(params);

        if (gridId != null) {
            List<Long> sourceIds = gridMemberBindResourcesBusiness.getSourceIdByGridIdAndSourceType(gridId, GridConstant.SourceType.BUILDING.getType());
            params.put(BUILDING_IDS, sourceIds);
        }

        return Response.<HouseholdCountDto>ok().wrap(householdService.countHousehold(params));
    }
}
